package com.storydo.file.share.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * <strong>Title : Strings </strong>. <br>
 * <strong>Description : 字符串处理工具类.</strong> <br>
 * <strong>Create on : May 20, 2015 5:32:38 PM </strong>. <br>
 * <p>
 * <strong>Copyright (C) AlexHo Co.,Ltd.</strong> <br>
 * </p>
 *
 * @author k2 <br>
 * @version <strong>base-platform-0.1.0</strong> <br>
 *          <br>
 *          <strong>修改历史: .</strong> <br>
 *          修改人 修改日期 修改描述<br>
 *          -------------------------------------------<br>
 *          <br>
 *          <br>
 */
public class Stringer {

	private static Logger logs = LoggerFactory.getLogger(Stringer.class);

	public static final String SPECIAL_CHAR = "[\\\\`~!@#$%^&*+=|{}',:;\"[url=file://\\[\\].<]\\[\\].<>/[/url]?～！＠＃￥％……＆×（）——＋｜｛｝【】［］‘；：＂。，、．＜＞／？]";

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 判断某字符串是否为空，如果为空，则返回一个空串.
	 * @param string
	 * @return
	 */
	public static String nullToEmpty(String string) {
		return isNullOrEmpty(string) ? "" : string;
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 判断某字符串是否为空，如果为空，则返回一个null空对象.
	 * @param string
	 * @return
	 */
	public static String emptyToNull(String string) {
		return isNullOrEmpty(string) ? null : string;
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 判断某对象(String,Collection,Map,obj)是否为空.
	 * @param obj
	 * @return
	 */
	public static boolean isNullOrEmpty(Object obj) {

		boolean result = true;
		if (obj == null) {
			return true;
		}
		if (obj instanceof String) {
			result = (obj.toString().trim().length() == 0) || obj.toString().trim().equals("null");
		} else if (obj instanceof Collection) {
			result = ((Collection<?>) obj).size() == 0;
		} else if (obj instanceof Map) {
			result = ((java.util.Map<?, ?>) obj).isEmpty();
		} else {
			result = ((obj == null) || (obj.toString().trim().length() < 1)) ? true : false;
		}
		return result;
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 处理读取InputStream数据流.
	 * @param in
	 * @return 输出二进制数据
	 * @throws IOException
	 */
	public static byte[] readInStream(InputStream in) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int len = 0;
		byte[] buffer = new byte[1024];
		while ((len = in.read(buffer)) > 0) {
			out.write(buffer, 0, len);
		}
		out.close();
		in.close();
		return out.toByteArray();
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc InputStream数据流转换成字符串.
	 * @param is
	 * @return
	 * @throws IOException
	 */
	public static String toInStream(InputStream is) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int i;
		while ((i = is.read()) != -1) {
			baos.write(i);
		}
		return baos.toString();
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 将字符串转成InputStream流.
	 * @param sInputString
	 * @return
	 */
	public static InputStream toInStream(String sInputString) {
		ByteArrayInputStream tInputStringStream = null;
		if (sInputString != null && !sInputString.trim().equals("")) {
			tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());
		}
		return tInputStringStream;
	}

	/**
	 * @author by K2 Aug 18, 2015
	 *
	 * @desc 小数点数据字符串转成保留两位小数的float数据类型.
	 * @param string
	 * @return
	 */
	public static float toFloat(String string) {
		float f = Float.parseFloat(string);
		BigDecimal b = new BigDecimal(f);
		float f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
		return f1;
	}

	/**
	 * @author by K2 Aug 18, 2015
	 *
	 * @desc 浮点型数据转换成两位小数点的字符串.
	 * @param f
	 * @return
	 */
	public static String toFloat(float f) {
		DecimalFormat decimalFormat = new DecimalFormat(".00");// 构造方法的字符格式这里如果小数不足2位,会以0补足.
		String p = decimalFormat.format(f);// format 返回的是字符串
		return p;
	}

	/**
	 * @author by K2 Aug 19, 2015
	 *
	 * @desc 双精度数据转换成两位小数点的字符串.
	 * @param string
	 * @return
	 */
	public static Double toDouble(String string) {
		float f = Float.parseFloat(string);
		BigDecimal b = new BigDecimal(f);
		Double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		return f1;
	}

	/**
	 * @author by K2 Aug 19, 2015
	 *
	 * @desc 双精度数据转换成两位小数点的字符串.
	 * @param dd
	 * @return
	 */
	public static String toDouble(Double dd) {
		return String.format("%.2f", dd);
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 替换特殊字符(全角&半角)..
	 * @param srcString
	 *            原字符串
	 * @param regEx
	 *            替换的正则表达式，如果为空则使用默认的正则表达式，变量=SPECIAL_CHAR
	 * @return
	 * @throws PatternSyntaxException
	 */
	public static String filterString(String srcString, String regEx) throws PatternSyntaxException {
		if (isNullOrEmpty(srcString)) {
			return "";
		}
		if (isNullOrEmpty(regEx)) {
			regEx = SPECIAL_CHAR;
		}
		return Pattern.compile(regEx).matcher(srcString).replaceAll("").replaceAll("[url=]\\\\[/url]", "").trim();
	}

	/**
	 * @author by K2 Aug 21, 2015
	 *
	 * @desc 检查指定字符串中是否包含特殊字符
	 *
	 * @param srcString
	 *            原字符串
	 * @param regEx
	 *            替换的正则表达式，如果为空则使用默认的正则表达式，变量=SPECIAL_CHAR
	 * @return 如果有返回true
	 */
	public static boolean existSpecialChar(String srcString, String regEx) {
		if (isNullOrEmpty(regEx)) {
			regEx = SPECIAL_CHAR;
		}
		Matcher m = Pattern.compile(regEx).matcher(srcString);
		return m.find();
	}

	/**
	 * 通过反射的方式遍历对象的属性和属性值，方便调试
	 *
	 * @param o
	 *            要遍历的对象
	 * @throws Exception
	 */
	public static void reflect(Object o) throws Exception {
		Class<?> cls = o.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			f.setAccessible(true);
			logs.debug("==>" + f.getName() + " -> " + f.get(o));
		}
	}

	/**
	 *
	 * @Title: nullToEmptyString @Description: TODO @param @param
	 *         o @param @return @return String @auther yaoyinchu @throws
	 */
	public static String nullOrEmptyToString(Object o) {
		if (Stringer.isNullOrEmpty(o)) {
			return "";
		} else {
			return o.toString();
		}
	}
}
